home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 2324 / 2324.xpi / modules / logger.js
Text File  |  2009-10-09  |  8KB  |  277 lines

  1. const Cc = Components.classes;
  2. const Ci = Components.interfaces
  3. const report = Components.utils.reportError;
  4.  
  5. // Configuration Constant Settings - Change for each addon
  6. const ADDON_NAME = "Session Manager";
  7. const FILE_NAME = "sessionmanager_log.txt";
  8. const LOG_ENABLE_PREFERENCE_NAME = "extensions.sessionmanager.logging";
  9. const LOG_LEVEL_PREFERENCE_NAME = "extensions.sessionmanager.logging_level";
  10.  
  11. var EXPORTED_SYMBOLS = ["logger", "logging_level"];
  12.  
  13. // singleton
  14. var gLogger = null;
  15.  
  16. // globals
  17. var logging_level = {};
  18. logging_level["STATE"] = 1;
  19. logging_level["TRACE"] = 2;
  20. logging_level["DATA"] = 4;
  21. logging_level["INFO"] = 8;
  22. logging_level["EXTRA"] = 16;
  23. logging_level["ERROR"] = 32;
  24.  
  25. var deletedLogOK = false;
  26.  
  27. // Function to create singleton of logging class
  28. function logger() {
  29.     // Create singleton if it does not exist
  30.     if (!gLogger) {
  31.         gLogger = new loggerClass();
  32.     }
  33.     
  34.     if (!deletedLogOK) {
  35.         deletedLogOK = gLogger.deleteLogFile();
  36.     }
  37.  
  38.     return gLogger;
  39. }
  40.  
  41. //
  42. // Logging Class
  43. //
  44. function loggerClass() {
  45.     this._init();
  46. }
  47.  
  48. loggerClass.prototype = {
  49.     _logged_Addons : false,
  50.  
  51.     // 
  52.     // Initialize variables
  53.     //
  54.     _init: function() {
  55.         // Store values of preferences and listen for changes
  56.         let pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
  57.         try {
  58.             this.logEnabled = pb.getBoolPref(LOG_ENABLE_PREFERENCE_NAME);
  59.             this.logLevel = pb.getIntPref(LOG_LEVEL_PREFERENCE_NAME);
  60.             
  61.             // Only add one observer
  62.             pb.addObserver(LOG_ENABLE_PREFERENCE_NAME, this, false);
  63.             pb.addObserver(LOG_LEVEL_PREFERENCE_NAME, this, false);
  64.         }
  65.         catch (ex) {
  66.             this.logEnabled = false;
  67.             this.logLevel = 0;
  68.             report(ex);
  69.         }
  70.  
  71.         // Get services
  72.         this.mPromptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
  73.         this.mConsoleService = Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService);
  74.     },
  75.  
  76.     observe: function(aSubject, aTopic, aData)
  77.     {
  78.         switch (aTopic)
  79.         {
  80.             case "nsPref:changed":
  81.                 let pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
  82.                 try {
  83.                     switch(aData) 
  84.                     {
  85.                         case LOG_ENABLE_PREFERENCE_NAME:
  86.                             this.logEnabled = pb.getBoolPref(LOG_ENABLE_PREFERENCE_NAME);
  87.                             break;
  88.                         case LOG_LEVEL_PREFERENCE_NAME:
  89.                             this.logLevel = pb.getIntPref(LOG_LEVEL_PREFERENCE_NAME);
  90.                             break;
  91.                     }
  92.                     break;
  93.                 }
  94.                 catch(ex) {
  95.                     report(ex);
  96.                 }
  97.         }
  98.     },
  99.     
  100.     //
  101.     // Utility to create an error message in the log without throwing an error.
  102.     //
  103.     logError: function(e, force) {
  104.         // If not an exception, just log it.
  105.         if (!e.message) {
  106.             this.log(e, force);
  107.             return;
  108.         }
  109.     
  110.         // Log Addons if haven't already and EOL character exists
  111.         if (!this._logged_Addons && this.mEOL) this.logExtensions();
  112.         
  113.         try { 
  114.             if (force || this.logEnabled) {
  115.                 let consoleError = Cc['@mozilla.org/scripterror;1'].createInstance(Ci.nsIScriptError);
  116.                 consoleError.init(e.message, e.fileName, e.lineNumber, e.lineNumber, e.columnNumber, 0, null);
  117.  
  118.                 this.mConsoleService.logStringMessage(ADDON_NAME + " (" + (new Date).toGMTString() + "): " + consoleError.toString());
  119.                 this.write_log((new Date).toGMTString() + "): " + consoleError + "\n");
  120.             }
  121.         }
  122.         catch (ex) {
  123.             dump (ex + "\n")
  124.         }
  125.     },
  126.  
  127.     //
  128.     // Log info messages
  129.     //
  130.     log: function(aMessage, level, force) {
  131.         // Log Addons if haven't already and EOL character exists
  132.         if (!this._logged_Addons && this.mEOL) this.logExtensions();
  133.     
  134.         if (!level) level = "INFO";
  135.         try {
  136.             if (force || (this.logEnabled && (logging_level[level] & this.logLevel))) {
  137.                 this.mConsoleService.logStringMessage(ADDON_NAME + " (" + (new Date).toGMTString() + "): " + aMessage);
  138.                 this.write_log((new Date).toGMTString() + "): " + aMessage + "\n");
  139.             }
  140.         }
  141.         catch (ex) { 
  142.             dump(ex + "\n"); 
  143.         }
  144.     },
  145.  
  146.     //
  147.     // Open Log File
  148.     //
  149.     openLogFile: function(aErrorString) {
  150.         if (!this.logFile.exists() || !(this.logFile instanceof Ci.nsILocalFile)) {
  151.             this.mPromptService.alert(null, ADDON_NAME, aErrorString);
  152.             return;
  153.         }
  154.         try {
  155.             // "Double click" the log file to open it
  156.             this.logFile.launch();
  157.         } catch (e) {
  158.             try {
  159.                 // If launch fails (probably because it's not implemented), let the OS handler try to open the log file
  160.                 let mimeInfoService = Cc["@mozilla.org/uriloader/external-helper-app-service;1"].getService(Ci.nsIMIMEService);
  161.                 let mimeInfo = mimeInfoService.getFromTypeAndExtension(mimeInfoService.getTypeFromFile(this.logFile), "txt");
  162.                 mimeInfo.preferredAction = mimeInfo.useSystemDefault;
  163.                 mimeInfo.launchWithFile(this.logFile);      
  164.             }
  165.             catch (ex)
  166.             {
  167.                 this.mPromptService.alert(null, ADDON_NAME, ex);
  168.             }
  169.         }
  170.     },
  171.     
  172.     //
  173.     // Set the Log File - This will throw if profile isn't lodaed yet
  174.     //
  175.     setLogFile: function() {
  176.         if (!this.logFile) {
  177.             try {
  178.                 // Get Profile folder and append log file name
  179.                 this.logFile = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("ProfD", Ci.nsILocalFile).clone();
  180.                 this.logFile.append(FILE_NAME);
  181.             }
  182.             catch (ex) { 
  183.                 this.logFile = null;
  184.                 return false;
  185.             }
  186.         }
  187.         return true;
  188.     },
  189.  
  190.     // 
  191.     // Delete Log File if it exists and not logging or it's too large (> 10 MB)
  192.     //
  193.     deleteLogFile: function(aForce) {
  194.         // If log file not stored, store it.  This will throw an exception if the profile hasn't been initialized so just exit in that case.
  195.         if (!this.logFile) {
  196.             if (!this.setLogFile()) return false;
  197.         }
  198.     
  199.         try { 
  200.             if (this.logFile.exists() && (aForce || !this.logEnabled || this.logFile.fileSize > 10485760)) {
  201.                 this.logFile.remove(false);
  202.                 return true;
  203.             }
  204.         }
  205.         catch (ex) { 
  206.             dump(ex + "\n"); 
  207.         }
  208.         return true;
  209.     },
  210.                  
  211.     //
  212.     // Write to Log File
  213.     // 
  214.     write_log: function(aMessage) {
  215.         // If log file not stored, store it.  This will throw an exception if the profile hasn't been initialized so just exit in that case.
  216.         if (!this.logFile) {
  217.             if (!this.setLogFile()) return;
  218.         }
  219.     
  220.         // If EOL character isn't stored, try to get it
  221.         if (!this.mEOL) {
  222.             // Try to get the most recent window to find the platform
  223.             let recentWindow = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow(null);
  224.             let platform = (recentWindow ? recentWindow.navigator.platform : null);
  225.             
  226.             if (platform) {
  227.                 // Set EOL character
  228.                 this.mEOL = /win|os[\/_]?2/i.test(platform)?"\r\n":/mac/i.test(platform)?"\r":"\n";
  229.             }
  230.         }
  231.     
  232.         try {
  233.             let stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
  234.             // ioFlags: write only, create file, append;    Permission: read/write owner
  235.             stream.init(this.logFile, 0x02 | 0x08 | 0x10, 0600, 0);
  236.             let cvstream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
  237.             cvstream.init(stream, "UTF-8", 0, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  238.  
  239.             cvstream.writeString(aMessage.replace(/[\n$]/g, (this.mEOL ? this.mEOL : "\n")));
  240.             cvstream.flush();
  241.             cvstream.close();
  242.         }
  243.         catch (ex) { 
  244.             dump(ex + "\n"); 
  245.         }
  246.     },
  247.     
  248.     //
  249.     // Log Extensions - Also log browser version
  250.     //
  251.     logExtensions: function() {
  252.         if (!this.logEnabled) return;
  253.         this._logged_Addons = true;
  254.  
  255.         let Application = null;
  256.         if (Cc["@mozilla.org/fuel/application;1"]) {
  257.             Application = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);
  258.         } else if (Cc["@mozilla.org/smile/application;1"]) {
  259.             Application = Cc["@mozilla.org/smile/application;1"].getService(Ci.smileIApplication);
  260.         }
  261.         if (!Application) return;
  262.         
  263.         // Log browser version
  264.         this.log("Browser = " + Application.id + " - " + Application.name + " " + Application.version, "INFO");
  265.         
  266.         // Log Addons
  267.         let extensions = Application.extensions.all;
  268.         if (extensions.length) {
  269.             this.log("Extensions installed and enabled:");
  270.             for (let i=0; i<extensions.length; i++) {
  271.                 if (extensions[i].enabled) {
  272.                     this.log(extensions[i].name + " " + extensions[i].version, "INFO");
  273.                 }
  274.             }
  275.         }
  276.     }
  277. }